package com.axapoint.opoc.service;
import java.io.File;
import java.io.StringWriter;
import java.util.Iterator;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.UriInfo;
import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.namespace.QName;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;

import oio.sagdok._1_0.OrganisationListOutputType;

import org.xml.sax.SAXException;

import com.axapoint.opoc.core.dao.ObjectRegistration;
import com.axapoint.opoc.core.dao.Organization;
import com.axapoint.opoc.core.dao.OrganizationFacade;
import com.axapoint.opoc.core.dao.TestConstants;

// POJO, no interface no extends

//Sets the path to base URL + /hello
@Path("/organisation/hent")
public class HentOrganization implements TestConstants {

	@Context
	UriInfo uriInfo;
	@Context
	Request request;
	public HentOrganization(UriInfo uriInfo, Request request) {
		this.uriInfo = uriInfo;
		this.request = request;
		
	}
	
	// This method is called if TEXT_PLAIN is request
	@GET
	@Produces(MediaType.TEXT_PLAIN)
	public String sayPlainTextHent() {
		return "getOrganization";
	}

	// This method is called if XMLis request
	@GET
	@Path("{uuid}")
	@Produces(MediaType.TEXT_XML)
	public String sayXMLHent() throws Exception {
		System.out.println("---- DEBUG --- XML");

		StringWriter sw = new StringWriter();
		
		JAXBContext jaxbContext = JAXBContext.newInstance("oio.sagdok._1_0");
		OrganisationListOutputType olo = OrganisationMapperOio.hentListe(t2, rt2, null);
		JAXBElement root = new JAXBElement(new QName("urn:oio:sagdok:1.0.0","OrganisationListOutputType"), OrganisationListOutputType.class, olo);
		jaxbContext.createMarshaller().marshal( root, sw);
		
		return sw.toString();
	}

	// This method is called if HTML is request
	@GET
	@Path("{uuid}")
	@Produces(MediaType.TEXT_HTML)
	public String sayHtmlHent(@PathParam("uuid")String id) throws Exception {
		OrganizationFacade orgFacade = new OrganizationFacade("RestWS", "Michael");

		Organization[] orgs = orgFacade.getAllEntities();
		
		StringBuffer sb = new StringBuffer();
		sb.append("<html> " + "<title>" + "organisation/hent/</title><body><h1>IT&T Sag & Dokument - organisation/hent/</h1>");
		
		sb.append("<table border='1'>");
		sb.append("<tr>");
		sb.append("<th>Organisation uuid</th>");
		sb.append("<th>Registrering</th>");
		sb.append("<th>Virkning</th>");
		sb.append("<th>Attributter</th>");
		sb.append("<th>Referencer</th>");
		sb.append("</tr>");
		for (Organization o : orgs) {
			
			Iterator it = o.getValues().getData().iterator();
			while (it.hasNext()) {
				Organization.Bitemporal bi = (Organization.Bitemporal)it.next();
				Organization.Value v = (Organization.Value)bi.getValue();
				
				sb.append("<tr>");
				sb.append("<td>").append(o.getUuid()).append("</td>");
				sb.append("<td>").append(ObjectRegistration.formatInterval(bi.getRecordInterval())).append("<br/>");
				sb.append(v.getUserId()).append('@').append(v.getSystemId()).append(" - ").append(v.getOperation()).append("</td>");
				sb.append("<td>").append(ObjectRegistration.formatInterval(bi.getValidityInterval())).append("</td>");				
				sb.append("<td>").append("Name: " + v.getName()).append("</td>");
				sb.append("<td>").append("Type: " + v.getOrganizationType().getUuid()).append("</td>");
				sb.append("</tr>");
			}
		}
		
		sb.append("</table>");
		sb.append("</body></html>");

		return sb.toString();
	}
	
	public static void main(String args[]) throws Exception {
		
//		JAXBContext jaxbContext = JAXBContext.newInstance("oio.sagdok._1_0");
		JAXBContext jaxbContext = JAXBContext.newInstance("generated");

/*		TidspunktType tt = new TidspunktType();
		tt.setTidspunktFaktisk(new FaktiskTidspunktType());
		tt.setTidspunktSpecielt(new SpecieltTidspunktType());
		tt.getTidspunktFaktisk().setTidsstempelDatoTid(AbstractMapper.dateTimeToXMLGregorianCalendar(new DateTime()));
		tt.getTidspunktSpecielt().setSpecieltTidspunktVaerdi(new BigInteger("0"));
		
		
		JAXBElement root = new JAXBElement(new QName("urn:oio:sagdok:1.0.0","TidspunktType"), tt.getClass(), tt);
		System.out.println("---- DEBUG root=" + root);

		Marshaller marshaller = jaxbContext.createMarshaller();
		marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
		marshaller.marshal(root, System.out);

	
		OrganisationListOutputType olo = OrganisationMapper.hentListeDummy(t2, rt2, null);
		JAXBElement root2 = new JAXBElement(new QName("urn:oio:sagdok:1.0.0","OrganisationListOutputType"), olo.getClass(), olo);
		System.out.println();
		System.out.println("---- DEBUG root2=" + root2);

		marshaller = jaxbContext.createMarshaller();
		marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
		marshaller.marshal(root2, System.out);
*/		
		// Load data
		unmarshal(JAXBContext.newInstance("oio.sagdok._1_0"), 
				"/Users/michael/workspaces/OPOC/opoc-service/xml/oio-organisation.xml",
				"/Users/michael/workspaces/OPOC/opoc-service/xsd/oio.xsd.xml");

		unmarshal(JAXBContext.newInstance("generated"), 
				"/Users/michael/workspaces/OPOC/opoc-service/xml/location.xml",
				"/Users/michael/workspaces/OPOC/opoc-service/xsd/opoc.location.xsd");
		
		unmarshal(JAXBContext.newInstance("generated"), 
				"/Users/michael/workspaces/OPOC/opoc-service/xml/location-noreg.xml",
				"/Users/michael/workspaces/OPOC/opoc-service/xsd/opoc.location.xsd");
	}

	private static void unmarshal(JAXBContext jaxbContext, String xmlFilename, String xsdFilename) throws JAXBException, SAXException {
		Unmarshaller um = jaxbContext.createUnmarshaller();

		System.out.println("---- Unmarshall WITHOUT validation: " + xmlFilename);
	//	Object data = um.unmarshal(new File(xmlFilename));
		
		System.out.println("---- Unmarshall WITH validation: "  + xmlFilename);
		SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
		Schema schema = sf.newSchema(new File(xsdFilename));
		
		um.setSchema(schema);
		um.unmarshal(new File(xmlFilename));		
	}
}